#!/bin/bash

. /etc/profile

# mysql
mysql_root_pass=DEF@67812
mysql_remote_connect=true
mysql_data_dir=/var/lib/mysql
mysql_install_dir=/usr/local/mysql
mysql_file=mysql-5.7.23-linux-glibc2.12-x86_64

# CDH
OFFLINE=false
mysql_scm_pass=DEF@67812
cdh_install_dir=/opt/cloudera-manager

# 输出样式
function ERROR() {
    printf "$(tput setaf 1)[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] ✖ %s $(tput sgr0)\n" "$@"
}

function INFO() {
    printf "$(tput setaf 2)[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] ➜ %s $(tput sgr0)\n" "$@"
}

function SUCCESS() {
    printf "$(tput setaf 3)[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] ✔ %s $(tput sgr0)\n" "$@"
}

function WARNING() {
    printf "$(tput setaf 5)[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING] ➜ %s $(tput sgr0)\n" "$@"
}

function CHECK() {
    printf "$(tput setaf 3)[$(date '+%Y-%m-%d %H:%M:%S')] [CHECK] ✔ %s $(tput sgr0)\n" "$@"
}

# Check command
CHECK_CMD() {
    command -v "$1" >/dev/null 2>&1
}

CHECK_FILE() {
    FILE_NEME=$1
    SERVER_DIR=$2
    if [ -f "$FILE_NEME" ]; then
        INFO "本地存在资源: $FILE_NEME"
    else
        INFO "下载资源: $FILE_NEME"
        curl -SLO --progress http://$SERVER_DIR/$FILE_NEME
    fi
}

function get_server() {
    ping -i 0.2 -c 3 -W 1 192.168.2.7 >&/dev/null
    if [ $? -eq 0 ]; then
        SERVER_DIR=192.168.2.7/cdh-5.16.1
    else
        SERVER_DIR=kaifa.hc-yun.com:30027/cdh-5.16.1
    fi
}

function prep() {
    INFO "关闭/禁用 Selinux"
    setenforce 0 >/dev/null 2>&1
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

    INFO "关闭防火墙"
    systemctl stop firewalld
    systemctl disable firewalld

    INFO "安装 ntp perl psmisc"
    yum install -y ntp perl psmisc
}

function install_ntp() {
    local role=$1
    local server_ip=$2

    function usage() {
        echo "-----------------------------------------"
        echo "Example:"
        echo -e "\t$0 server"
        echo -e "\t$0 agent $server_ip"
    }

    [ -n "$role" ] || usage
    if [ "$role" == 'agent' ]; then
        [ -n "$server_ip" ] || usage
    fi

    if ! CHECK_CMD ntpdate; then
        INFO "安装htp"
        yum install -y ntp
    fi

    INFO "同步外网时间"
    /usr/sbin/ntpdate ntp6.aliyun.com

    cp -f /etc/ntp.conf /etc/ntp.conf.$(date +"%F-%T")
    # 公共配置
    echo 'driftfile /var/lib/ntp/drift' >/etc/ntp.conf
    echo 'restrict default kod nomodify notrap nopeer noquery' >>/etc/ntp.conf
    echo 'restrict -6 default kod nomodify notrap nopeer noquery' >>/etc/ntp.conf
    echo 'restrict 127.0.0.1' >>/etc/ntp.conf
    echo 'restrict -6 ::1' >>/etc/ntp.conf
    echo 'includefile /etc/ntp/crypto/pw' >>/etc/ntp.conf
    echo 'keys /etc/ntp/keys' >>/etc/ntp.conf

    if [[ "$role" == 'server' ]]; then
        # 获取内网网段
        host_if=$(ip route | grep default | cut -d' ' -f5)
        host_ip=$(ip a | grep "$host_if$" | awk '{print $2}' | cut -d'/' -f1)
        sub_net="$(echo $host_ip | cut -d '.' -f 1-3).0"

        # 外部NTP服务
        echo 'server ntp6.aliyun.com perfer' >>/etc/ntp.conf
        echo 'server cn.ntp.org.cn iburst' >>/etc/ntp.conf
        echo 'server ntp.shu.edu.cn iburst' >>/etc/ntp.conf
        echo 'server s2c.time.edu.cn iburst' >>/etc/ntp.conf

        # 允许上层服务主动修改本机时间
        echo 'restrict ntp6.aliyun.com nomodify notrap noquery' >>/etc/ntp.conf
        echo 'restrict cn.ntp.org.cn nomodify notrap noquery' >>/etc/ntp.conf

        # 外部时间服务器不可用时，以本地时间作为时间服务
        echo 'server  127.127.1.0     # local clock' >>/etc/ntp.conf
        echo 'fudge   127.127.1.0 stratum 10' >>/etc/ntp.conf

        # 作为内网某个网段提供NTP服务
        echo "restrict $sub_net mask 255.255.255.0 nomodify notrap" >>/etc/ntp.conf
    elif [[ "$role" == 'agent' ]]; then
        # 使用内网NTP服务
        echo "server $server_ip iburst" >>/etc/ntp.conf
        echo "restrict $server_ip nomodify notrap noquery" >>/etc/ntp.conf
    else
        usage
    fi

    # 外部时间服务器不可用时，以本地时间作为时间服务
    echo 'server  127.127.1.0     # local clock' >>/etc/ntp.conf
    echo 'fudge   127.127.1.0 stratum 10' >>/etc/ntp.conf

    # 检测系统版本
    if [[ $(uname -r) =~ 'el6' ]]; then
        chkconfig ntpd on
        service ntpd start
    else
        systemctl enable ntpd
        systemctl restart ntpd
    fi

    /usr/sbin/hwclock -w

    INFO "NTP服务 状态检测"
    ntpstat
    ntpq -p
}

function install_java() {
    # 检测是否安装 JDK
    if CHECK_CMD java; then
        CHECK 'JDK 环境已经存在'
        return
    fi

    # 下载jdk
    mkdir -p /usr/java
    CHECK_FILE jdk-8u211-linux-x64.tar.gz $SERVER_DIR

    INFO '解压 jdk-8u211-linux-x64.tar.gz 到目录 /usr/java'
    tar zxf jdk-8u211-linux-x64.tar.gz -C /usr/java/
    if [ $? -ne 0 ]; then
        ERROR '解压失败请检查安装包完整性'
        exit 1
    fi

    # 配置环境变量
    INFO '配置 JDK 环境变量'
    echo '#!/bin/bash' >/etc/profile.d/jdk.sh
    echo 'export JAVA_HOME=/usr/java/jdk1.8.0_211' >>/etc/profile.d/jdk.sh
    echo 'export JRE_HOME=${JAVA_HOME}/jre' >>/etc/profile.d/jdk.sh
    echo 'export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH' >>/etc/profile.d/jdk.sh
    echo 'export PATH=$JAVA_HOME/bin:$PATH' >>/etc/profile.d/jdk.sh

    # 读取环境变量
    chmod +x /etc/profile.d/jdk.sh
    source /etc/profile.d/jdk.sh
}

function install_mysql() {
    # 检测是否安装 JDK
    if CHECK_CMD mysql; then
        CHECK 'MySql 已存在'
        return
    fi

    INFO "安装依赖"
    yum install -y libaio numactl-libs &>/dev/null

    CHECK_FILE ${mysql_file}.tar.gz $SERVER_DIR

    INFO "解压MySQL: ${mysql_file}.tar.gz"
    tar zxf ${mysql_file}.tar.gz
    if [ $? -ne 0 ]; then
        ERROR '解压失败请检查安装包完整性'
        exit 1
    fi

    INFO "创建MySQL服务用户"
    if ! id mysql >/dev/null 2>&1; then
        groupadd -g 1200 mysql
        useradd -r -g mysql -u 1200 -s /sbin/nologin mysql
    fi

    INFO "创建MySQL安装目录: $mysql_install_dir  创建MySQL数据目录: $mysql_data_dir"
    mkdir -p $mysql_install_dir $mysql_data_dir
    mv $mysql_file/* $mysql_install_dir
    rm -rf $mysql_file

    INFO "配置MySQL服务管理 systemd"
    cp $mysql_install_dir/support-files/mysql.server /etc/init.d/mysqld
    sed -i "s@^basedir=.*@basedir=$mysql_install_dir@" /etc/init.d/mysqld
    sed -i "s@^datadir=.*@datadir=$mysql_install_dir@" /etc/init.d/mysqld
    chmod +x /etc/init.d/mysqld
    chkconfig --add mysqld
    chkconfig mysqld on

    INFO "创建环境变量"
    echo "export PATH=$mysql_install_dir/bin:\$PATH" >>/etc/profile
    . /etc/profile

    INFO "创建MySQL配置文件: /etc/my.cnf"
    cat >/etc/my.cnf <<EOF
[mysqld]
datadir=$mysql_data_dir
socket=$mysql_data_dir/mysql.sock
transaction-isolation = READ-COMMITTED
# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
symbolic-links = 0

key_buffer_size = 32M
max_allowed_packet = 32M
thread_stack = 256K
thread_cache_size = 64
query_cache_limit = 8M
query_cache_size = 64M
query_cache_type = 1

max_connections = 550
#expire_logs_days = 10
#max_binlog_size = 100M

#log_bin should be on a disk with enough free space.
#Replace '/var/lib/mysql/mysql_binary_log' with an appropriate path for your
#system and chown the specified folder to the mysql user.
log_bin=$mysql_data_dir/mysql_binary_log

#In later versions of MySQL, if you enable the binary log and do not set
#a server_id, MySQL will not start. The server_id must be unique within
#the replicating group.
server_id=1

binlog_format = mixed

read_buffer_size = 2M
read_rnd_buffer_size = 16M
sort_buffer_size = 8M
join_buffer_size = 8M

# InnoDB settings
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit  = 2
innodb_log_buffer_size = 64M
innodb_buffer_pool_size = 4G
innodb_thread_concurrency = 8
innodb_flush_method = O_DIRECT
innodb_log_file_size = 512M

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=$mysql_data_dir/mysqld.pid

sql_mode=STRICT_ALL_TABLES

[client]
socket=$mysql_data_dir/mysql.sock
EOF

    INFO "初始化MySQL"
    chmod 600 /etc/my.cnf
    chown mysql.mysql -R $mysql_data_dir
    $mysql_install_dir/bin/mysqld --defaults-file=/etc/my.cnf --initialize-insecure --user=mysql --basedir=$mysql_install_dir --datadir=$mysql_data_dir >/dev/null 2>&1

    INFO "启动MySQL服务"
    systemctl restart mysqld

    INFO "设置MySQL密码"
    mysql -e "grant all privileges on *.* to root@'127.0.0.1' identified by \"${mysql_root_pass}\" with grant option;"
    mysql -e "grant all privileges on *.* to root@'localhost' identified by \"${mysql_root_pass}\" with grant option;"
    mysql -uroot -p${mysql_root_pass} -e "show databases;"

    if [ "$mysql_remote_connect" == 'true' ]; then
        INFO "启用MySQL root用户远程登入"
        mysql -uroot -p${mysql_root_pass} -e "grant all privileges on *.* to root@'%' identified by \"${mysql_root_pass}\" with grant option;"
        mysql -uroot -p${mysql_root_pass} -e "SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;"
    fi

    #INFO "配置防火墙: 3306/tcp"
    #if systemctl status firewalld >/dev/null 2>&1; then
    #    firewall-cmd --zone=public --add-port=3306/tcp --permanent >/dev/null 2>&1
    #    firewall-cmd --reload >/dev/null 2>&1
    #fi
}

function mysql_connector_java() {
    INFO "配置 mysql-connector-java 驱动"
    CHECK_FILE mysql-connector-java-5.1.48.tar.gz $SERVER_DIR

    INFO "解压/配置 mysql-connector-java 驱动"
    tar zxf mysql-connector-java-5.1.48.tar.gz
    if [ $? -ne 0 ]; then
        ERROR '解压失败请检查安装包完整性'
        exit 1
    fi
    mkdir -p /usr/share/java/
    cp mysql-connector-java-5.1.48/mysql-connector-java-5.1.48-bin.jar /usr/share/java/mysql-connector-java.jar
    rm -rf mysql-connector-java-5.1.48
}

function cdh_server() {
    prep
    install_ntp server
    get_server
    install_java
    install_mysql
    mysql_connector_java

    INFO "MySQL创建 scm 数据库/账号"
    echo "CREATE DATABASE scm DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;" | mysql -u root -p${mysql_root_pass}
    echo "GRANT ALL ON scm.* TO 'scm'@'%' IDENTIFIED BY \"${mysql_scm_pass}\";" | mysql -u root -p${mysql_root_pass}

    INFO "下载/解压 cloudera-manager"
    CHECK_FILE cloudera-manager-centos7-cm5.16.1_x86_64.tar.gz $SERVER_DIR
    mkdir -p $cdh_install_dir
    # cp /usr/share/java/mysql-connector-java-5.1.48-bin.jar $cdh_install_dir/cm-5.16.1/share/cmf/lib/
    tar -zxf cloudera-manager-centos7-cm5.16.1_x86_64.tar.gz -C $cdh_install_dir
    if [ $? -ne 0 ]; then
        ERROR '解压失败请检查安装包完整性'
        exit 1
    fi

    INFO "创建服务用户 cloudera-scm"
    if ! id cloudera-scm >/dev/null 2>&1; then
        useradd --system --home=$cdh_install_dir/cm-5.16.1/run/cloudera-scm-server --no-create-home --shell=/bin/false --comment "Cloudera SCM User" cloudera-scm
    fi

    INFO "配置 cloudera-scm server_host"
    host_if=$(ip route | grep default | cut -d' ' -f5)
    host_ip=$(ip a | grep "$host_if$" | awk '{print $2}' | cut -d'/' -f1)
    sed -i "s#server_host=.*#server_host=$host_ip#" $cdh_install_dir/cm-5.16.1/etc/cloudera-scm-agent/config.ini
    chown -R cloudera-scm:cloudera-scm $cdh_install_dir

    INFO "创建 scm 初始化数据表"
    $cdh_install_dir/cm-5.16.1/share/cmf/schema/scm_prepare_database.sh mysql scm scm $mysql_scm_pass
    if [ $? -eq 0 ]; then
        SUCCESS "初始化数据表 成功"
    else
        ERROR "初始化数据表 失败"
        exit 1
    fi

    INFO "创建离线资源"
    mkdir -p /opt/cloudera/parcel-repo
    chown cloudera-scm:cloudera-scm /opt/cloudera/parcel-repo

    if [ "$OFFLINE" == 'true' ]; then
        INFO "检测/下载 CDH 离线资源"
        cd /opt/cloudera/parcel-repo
        CHECK_FILE manifest.json $SERVER_DIR
        CHECK_FILE CDH-5.16.1-1.cdh5.16.1.p0.3-el7.parcel $SERVER_DIR
        CHECK_FILE CDH-5.16.1-1.cdh5.16.1.p0.3-el7.parcel.sha1 $SERVER_DIR
        mv CDH-5.16.1-1.cdh5.16.1.p0.3-el7.parcel.sha1 CDH-5.16.1-1.cdh5.16.1.p0.3-el7.parcel.sha
    fi

    # 临时优化参数
    echo 10 >/proc/sys/vm/swappiness
    echo never >/sys/kernel/mm/transparent_hugepage/defrag
    echo never >/sys/kernel/mm/transparent_hugepage/enabled

    # 永久优化参数
    if [ ! "$(grep -rn 'vm.swappiness' /etc/sysctl.conf)" ]; then
        echo 'vm.swappiness=10' >>/etc/sysctl.conf
        echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >>/etc/rc.local
        echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.local
    fi

    #INFO "配置防火墙: 7180 7182 9000/tcp"
    #if systemctl status firewalld >/dev/null 2>&1 ; then
    #    firewall-cmd --zone=public --add-port=7180/tcp --permanent >/dev/null 2>&1
    #    firewall-cmd --zone=public --add-port=7182/tcp --permanent >/dev/null 2>&1
    #    firewall-cmd --zone=public --add-port=9000/tcp --permanent >/dev/null 2>&1
    #    firewall-cmd --reload >/dev/null 2>&1
    #fi
}

function cdh_agent() {
    # 检测主节点变量是否存在
    if [ -z "$1" ]; then
        ERROR "主节点IP变量为空 \$cloudera_scm_master_ip"
        exit 1
    else
        cloudera_scm_master_ip=$1
    fi

    prep
    install_ntp agent $cloudera_scm_master_ip
    get_server
    install_java
    mysql_connector_java

    INFO "下载/解压 cloudera-manager"
    CHECK_FILE cloudera-manager-centos7-cm5.16.1_x86_64.tar.gz $SERVER_DIR
    mkdir -p $cdh_install_dir
    # cp /usr/share/java/mysql-connector-java-5.1.48-bin.jar $cdh_install_dir/cm-5.16.1/share/cmf/lib/
    tar -zxf cloudera-manager-centos7-cm5.16.1_x86_64.tar.gz -C $cdh_install_dir
    if [ $? -ne 0 ]; then
        ERROR '解压失败请检查安装包完整性'
        exit 1
    fi

    INFO "创建服务用户 cloudera-scm"
    if ! id cloudera-scm >/dev/null 2>&1; then
        useradd --system --home=$cdh_install_dir/cm-5.16.1/run/cloudera-scm-server --no-create-home --shell=/bin/false --comment "Cloudera SCM User" cloudera-scm
    fi

    INFO "配置 cloudera-scm server_host"
    sed -i "s#server_host=.*#server_host=$cloudera_scm_master_ip#" $cdh_install_dir/cm-5.16.1/etc/cloudera-scm-agent/config.ini
    chown -R cloudera-scm:cloudera-scm $cdh_install_dir

    # 临时优化参数
    echo 10 >/proc/sys/vm/swappiness
    echo never >/sys/kernel/mm/transparent_hugepage/defrag
    echo never >/sys/kernel/mm/transparent_hugepage/enabled

    # 永久优化参数
    if [ ! "$(grep -rn 'vm.swappiness' /etc/sysctl.conf)" ]; then
        echo 'vm.swappiness=10' >>/etc/sysctl.conf
        echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >>/etc/rc.local
        echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.local
    fi

    #INFO "配置防火墙: 9000/tcp"
    #if systemctl status firewalld >/dev/null 2>&1 ; then
    #    firewall-cmd --zone=public --add-port=9000/tcp --permanent >/dev/null 2>&1
    #    firewall-cmd --reload >/dev/null 2>&1
    #fi
}

case $1 in
    server)
        cdh_server
        ;;
    agent)
        cdh_agent $2
        ;;
    *)
        echo "Usage $0 {server|agent}"
        echo "$0 server"
        echo "$0 agent server_ip"
        ;;
esac

unset mysql_root_pass mysql_scm_pass

cat <<EOF

master:
    cd  $cdh_install_dir/cm-5.16.1/etc/init.d
    ./cloudera-scm-agent start
    ./cloudera-scm-server start

slave:
    cd  $cdh_install_dir/cm-5.16.1/etc/init.d
    ./cloudera-scm-agent start

浏览器打开 http://master_ip:7180    admin/admin
    
    在线安装:
      添加安装源
        内网: http://192.168.2.7/cdh-5.16.1
        外网: http://kaifa.hc-yun.com:30027/cdh-5.16.1

    离线安装:
      将资源放到目录: /opt/cloudera/parcel-repo
EOF